#ifdef SU1
#define _GLIBCXX_DEBUG
#endif

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define sz(a) (int) (a).size()
#define all(a) (a).begin(), (a).end()
#define ft first
#define sc second
#define x first
#define y second

template<typename X> inline X abs(const X& a) { return a < 0 ? -a : a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld PI = acosl(ld(-1));
const ld EPS = 1e-9;

const int N = 10 * 1000 + 13;

int n, m, k, s, t;
pt e[N];

inline bool read()
{
	if (scanf("%d%d%d%d%d", &n, &m, &k, &s, &t) != 5) return false;
	--s, --t;
	forn(i, m) assert(scanf("%d%d", &e[i].ft, &e[i].sc) == 2), e[i].ft--, e[i].sc--;
	return true;
}

struct edge
{
	int to, f, c, rev;
};

vector<edge> g[N];

void add (int from, int to, int cap)
{
	edge f = { to, 0, cap, sz(g[to]) };
	edge b = { from, 0, 0, sz(g[from]) };
	g[from].pb(f);
	g[to].pb(b);
}

int level[N], q[N], tail, head, ptr[N];

inline bool bfs (int s, int t)
{
	forn(i, t + 1) level[i] = INF;
	level[s] = 0;
	
	tail = head = 0;
	q[tail++] = s;
	
	while (tail != head)
	{
		int v = q[head++];
		
		forn(i, sz(g[v]))
		{
			const edge& e = g[v][i];
			if (e.f < e.c && level[e.to] > level[v] + 1)
			{
				level[e.to] = level[v] + 1;
				q[tail++] = e.to;
			}
		}
	}
	
	return level[t] < INF / 2;
}

bool dfs (int v, int t)
{
	if (v == t) return true;
	
	for (; ptr[v] < sz(g[v]); ptr[v]++)
	{
		edge& e = g[v][ptr[v]];
		if (e.f == e.c || level[v] + 1 != level[e.to]) continue;
		if (dfs(e.to, t))
		{
			e.f++;
			g[e.to][e.rev].f--;
			return true;
		}
	}
	return false;
}

int dinic (int s, int t)
{
	int ans = 0;
	while (true)
	{
		if (!bfs(s, t)) break;
		forn(i, t + 1) ptr[i] = 0;
		while (true)
		{
			bool f = dfs(s, t);
			if (f == 0) break;
			ans++;
		}
	}
	return ans;
}

inline int can (int mid)
{
	int S = n * mid, T = S + 1;
	
	forn(i, T + 1) g[i].clear();
	
	forn(i, mid)
	{
		add(S, n * i + s, INF);
		add(n * i + t, T, INF);
		
		if (i + 1 < mid)
		{
			forn(j, m)
			{
				int a = e[j].ft, b = e[j].sc;
				add(n * i + a, n * (i + 1) + b, 1);
				add(n * i + b, n * (i + 1) + a, 1);
			}
		}
	}
	
	return dinic(S, T);
}

vector<int> initg[N];

vector<int> way;

void fleury (int v)
{
	while (!initg[v].empty())
	{
		int to = initg[v].back();
		initg[v].pop_back();
		fleury(to);
	}
	way.pb(v);
}

vector<vector<pt> > ans;

vector<pt> res[N];

inline void solve()
{
	int lf = 1, rg = 100 + 13;
	while (lf != rg)
	{
		int mid = (lf + rg) >> 1;
		if (can(mid) >= k)
			rg = mid;
		else
			lf = mid + 1;
	}
	int ansflow = can(lf);
	assert(ansflow >= k);
	
	//cerr << lf << ' ' << ansflow << endl;
	
	int S = n * lf, T = S + 1;
	
	forn(i, T + 1) forn(j, sz(g[i]))
		forn(k, g[i][j].f) initg[i].pb(g[i][j].to);
		
	forn(i, ansflow) initg[T].pb(S);
	
	fleury(S);
	reverse(all(way));
	
	//forn(i, sz(way)) cerr << way[i] << ' '; cerr << endl;
	
	assert(way[0] >= S && way.back() >= S);
	
	for (int i = 0; i < sz(way); i++)
	{
		if (way[i] >= S) continue;
		vector<pt> cur;
		while (i < sz(way) && way[i] < S)
		{
			cur.pb(mp(way[i] / n, way[i] % n));
			i++;
		}
		ans.pb(cur);
		if (sz(ans) == k) break;
	}
	
	//forn(i, sz(ans)) { forn(j, sz(ans[i])) cerr << "(" << ans[i][j].ft << ", " << ans[i][j].sc << ") "; cerr << endl; }

	forn(i, sz(ans)) forn(j, sz(ans[i]))
	{
		if (ans[i][j].sc == s) continue;
		res[ans[i][j].ft - 1].pb(mp(i, ans[i][j].sc));
	}
	
	int ansVal = lf - 1;
	
	cout << ansVal << endl;
	
	forn(i, ansVal)
	{
		printf("%d", sz(res[i]));
		forn(j, sz(res[i])) printf(" %d %d", res[i][j].ft + 1, res[i][j].sc + 1);
		puts("");
	}
}

int main()
{
#ifdef SU1
	assert(freopen("input.txt", "rt", stdin));
//	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(5);

	assert(read());
	solve();
	
#ifdef SU1
	cerr << "=== TIME : " << clock() << " ===" << endl;
#endif
	return 0;
}
